#include "IsometricMap.h"

IsometricMap::IsometricMap():
	mheight(0),
	mpSprites(nullptr),
	mpTiles(nullptr),
	mNumSprites(0),
	mTileSizeW(0),
	mTileSizeH(0),
	mColumns(0),
	mRows(0),
	mOffset(IniFile_GetInt("WinWidth", 800)/2,IniFile_GetInt("WinHeight", 800)/2)
{}
IsometricMap::~IsometricMap()
{}
void IsometricMap::Load(const char* pLevel, const char* pTexturePack)
{
	Unload();

	if(!LoadLevel(pLevel))
	{
		Unload();
		return;
	}
	else if(!LoadTexturePack(pTexturePack))
	{
		Unload();
		return;
	}
}
void IsometricMap::Unload()
{
	for(int i = 0; i < mNumSprites; ++i)
	{
		mpSprites[i].Unload();
	}
	delete [] mpSprites;
	delete [] mpTiles;
	mpTiles = nullptr;
	mTileSizeH = 0;
	mTileSizeW = 0;
	mColumns = 0;
	mRows = 0;
}
void IsometricMap::Update(float deltaTime)
{

}
void IsometricMap::Render()
{
	SVector2 windowsSize(IniFile_GetFloat("WinWidth", 800),IniFile_GetFloat("WinHeight", 800));
	SVector2 side(IniFile_GetFloat("WinWidth", 800)/5,IniFile_GetFloat("WinHeight", 800)/5);
	float tileHeight((mRows+mColumns)*mTileSizeH);
	for(int y = 0; y < mRows; ++y)
	{
		for(int x = 0; x < mColumns; ++x)
		{
			double move(0.01);
			const int index = GetIndex2D(x, y);
			//SVector2 pos(((x-y) * (mTileSizeW/2)), ((x+y)* (mTileSizeH/2))); 
			SVector2 pos(GetScreenPositionPixelTile(SVector2(x,y)));
			if(Input_GetMouseScreenY() < side.y && mOffset.y >= 0.0f)
			{
				mOffset.y -= move;
			}
			if(Input_GetMouseScreenY() > (windowsSize.y - side.y) && mOffset.y <= windowsSize.y)
			{
				if(mOffset.y <= (windowsSize.y-(tileHeight/2)))
				{
					mOffset.y += move;
				}
			}
			SVector2 renderPos = pos + mOffset;// - viewOffset
			mpSprites[mpTiles[index]].SetPosition(renderPos);
			mpSprites[mpTiles[index]].Render();
		}
	}
	
}
bool IsometricMap::LoadLevel(const char* pLevel)
{
	FILE * pFile(nullptr);
	fopen_s(&pFile, pLevel, "r");
	if(pFile == nullptr)
	{
		return false;
	}
	else
	{
		fscanf_s(pFile, "%*s %d", &mTileSizeH);
		fscanf_s(pFile, "%*s %d", &mTileSizeW);
		fscanf_s(pFile, "%*s %d", &mColumns);
		fscanf_s(pFile, "%*s %d", &mRows);

		mpTiles = new int[mColumns*mRows];

		fgetc(pFile);
		for(int y = 0; y< mRows; ++y)
		{
			for(int x = 0; x < mColumns; ++x)
			{
				const int index = GetIndex2D(x,y);
				mpTiles[index] = fgetc(pFile) - '0';
			}
			fgetc(pFile);
		}
	}
	fclose(pFile);
	return true;
}
bool IsometricMap::LoadTexturePack(const char* pTexturePack)
{
	FILE* pFile = nullptr;

	fopen_s(&pFile, pTexturePack, "r");
	if(pFile == nullptr)
	{
		return false;
	}
	else
	{
		fscanf_s(pFile, "%*s %d", &mNumSprites);
		mpSprites = new SGE_Sprite[mNumSprites];

		char buffer[256];
		for(int i = 0; i < mNumSprites; ++i)
		{
			fscanf_s(pFile, "%s", buffer, 256);
			mpSprites[i].Load(buffer);
		}
	}
	fclose(pFile);
	return true;
}
int IsometricMap::GetIndex2D(int x, int y) const
{
	return x + (y * mColumns);
}

SVector2 IsometricMap::GetScreenCoordinate(SVector2 coor) const
{
	/*float halfWidth = mTileSizeW/2.0f;
	float halfHeight = mTileSizeH/2.0f;
	SVector2 Coordinate;
	Coordinate.x =(int)(((coor.x-halfWidth)/halfWidth) + ((coor.y+(halfWidth/2))/halfHeight))/2;
	Coordinate.y =(int)(((coor.y+(halfHeight))/halfHeight) - ((coor.x-(halfWidth))/halfWidth))/2;
	return Coordinate;*/
	SVector2 Coordinate;
	float halfWidth = mTileSizeW/2.0f;
	float halfHeight = mTileSizeH/2.0f;
	Coordinate.x =(int)(((coor.x-halfWidth)/halfWidth) + ((coor.y+(halfWidth/2))/halfHeight))/2;
	Coordinate.y =(int)(((coor.y+(halfHeight))/halfHeight) - ((coor.x-(halfWidth))/halfWidth))/2;
	return Coordinate;
}
SVector2 IsometricMap::GetScreenCoordinateChar() const
{
	float	xPos(Input_GetMouseScreenX())
		,	yPos(Input_GetMouseScreenY());
	xPos -= mOffset.x;
	yPos -= mOffset.y;
	SVector2 Coordinate;
	float halfWidth = mTileSizeW/2.0f;
	float halfHeight = mTileSizeH/2.0f;
	/*Coordinate.x = (int)(((xPos-(mTileSizeW/2))/(mTileSizeW/2))	+	(yPos+(mTileSizeH/2))/(mTileSizeH/2))/2;
	Coordinate.y = (int)(((yPos+(mTileSizeH/2))/(mTileSizeH/2))	-	(xPos-(mTileSizeW/2))/(mTileSizeW/2))/2;*/
	Coordinate.x =(int)(((xPos-halfWidth)/halfWidth) + ((yPos+(halfWidth/2))/halfHeight))/2;
	Coordinate.y =(int)(((yPos+(halfHeight))/halfHeight) - ((xPos-(halfWidth))/halfWidth))/2;
	return Coordinate;
}

SVector2 IsometricMap::GetScreenPositionPixelTile(SVector2 coor) const
{
	SVector2 pixelCoor;
	/*pixelCoor.x = (coor.x - coor.y) * (mTileSizeW/2) + (mTileSizeW/2);
	pixelCoor.y = (coor.x + coor.y) * (mTileSizeH/2) - (mTileSizeH/2);*/
	pixelCoor.x = (coor.x - coor.y) * (mTileSizeW/2);
	pixelCoor.y = (coor.x + coor.y) * (mTileSizeH/2);
	return pixelCoor;
}
SVector2 IsometricMap::GetScreenPositionPixelChar(SVector2 coor) const
{
	SVector2 pixelCoor;
	pixelCoor.x = (coor.x - coor.y) * (mTileSizeW/2) + (mTileSizeW/2);
	pixelCoor.y = (coor.x + coor.y) * (mTileSizeH/2) - (mTileSizeH/2);
	return pixelCoor;
}